package partners

import (
	"gitee.com/theegg/go-brick/app/model"
	"gitee.com/theegg/go-brick/app/model/admin/admin_users"
	"gitee.com/theegg/go-brick/app/service/app"
	"gitee.com/theegg/go-brick/app/service/help/cmd5"
	"gitee.com/theegg/go-brick/app/service/help/cstring"
	"strconv"
)

// 添加参数
type PartnerAddParams struct {
	Id          int64  `form:"id" binding:"" label:"ID"`
	PartnerName string `form:"partner_name"  binding:"required,customName=6 36,customFiledUnique=partners partner_name" label:"租户名"`
	PartnerSign string `form:"partner_sign"  binding:"required,customSign=4 16,customFiledUnique=partners partner_sign" label:"租户标识"`
	Remark      string `form:"remark"  binding:"required,customPlainText=2 128" label:"描述"`
	DbRegion    string `form:"db_region"  binding:"required,customSign=4 16" label:"数据区域"`
}

// 查询参数
type PartnerQueryParams struct {
	PageSize    string `form:"page_size" binding:"gte=0,lte=100" label:"每页数量"`
	PageIndex   string `form:"page_index" binding:"gte=0,lte=99999" label:"当前页数"`
	PartnerName string `form:"partner_name"  binding:"" label:"租户名称"`
	PartnerSign string `form:"partner_sign"  binding:"" label:"租户标识"`
}

var DefaultPartnerSign = "default"
var DefaultDbRegion = "default"
var DbRegionOptions = map[string]string{
	"default":   "默认区域",
	"huadong01": "香港01",
	"huadong02": "华东02",
	"huadong03": "华东03",
}

// 分页获取所有数据
// @param params map 参数
// @return interface{}, error
func GetDataList(params map[string]interface{}) (map[string]interface{}, error) {
	returnData := make(map[string]interface{}, 0)

	queryParams, errBuild := model.BuildAdminQueryParam(params)
	if errBuild != nil {
		return nil, app.NewError(errBuild)
	}

	query := app.Db().Desc("id").Limit(queryParams.Limit, queryParams.Offset)

	// query partner_name
	if _, ok := queryParams.Params["partner_name"]; ok && queryParams.Params["partner_name"] != "" {
		query.Where("partner_name = ?", queryParams.Params["partner_name"])
	}

	// query partner_sign
	if _, ok := queryParams.Params["partner_sign"]; ok && queryParams.Params["partner_sign"] != "" {
		query.Where("partner_sign = ?", queryParams.Params["partner_sign"])
	}

	data := make([]Partners, 0)

	// 求总条数
	total, err := query.FindAndCount(&data)
	if err != nil {
		return nil, app.NewError(err)
	}

	for i, v := range data {
		data[i].Key = cstring.HideMiddleString(v.Key, 3, 3)
	}

	returnData["data"] = data
	returnData["total"] = total

	return returnData, nil
}

// @title AddOrUpdate
// @description 更新或者添加
func (p *Partners) AddOrUpdate(params PartnerAddParams, currentAdminUser *admin_users.AdminUsers) error {
	p.PartnerName = params.PartnerName
	p.Remark = params.Remark

	// 6. 开启事务 插入数据
	session := app.Db().NewSession()
	defer session.Close()
	errSb := session.Begin()
	if errSb != nil {
		return app.NewError(errSb)
	}

	if p != nil && p.Id > 0 {
		affected, errUpdate := session.ID(p.Id).Update(p)

		if errUpdate != nil {
			session.Rollback()
			return app.NewError(errUpdate)
		}

		if affected != 1 {
			session.Rollback()
			return app.NewError("更新错误")
		}
	} else {
		// 数据区域
		if _, ok := DbRegionOptions[params.DbRegion]; !ok {
			session.Rollback()
			return app.NewError("无效的数据区域")
		}

		p.DbRegion = params.DbRegion
		p.PartnerSign = params.PartnerSign
		if currentAdminUser != nil {
			p.AddAdminId = currentAdminUser.Id
		} else {
			p.AddAdminId = 0
		}

		affected, errInsert := session.Insert(p)
		if errInsert != nil {
			session.Rollback()
			return app.NewError(errInsert)
		}

		if affected != 1 {
			session.Rollback()
			return app.NewError("新增内容分类错误(0x001)")
		}

		// 更新key
		strId := strconv.FormatInt(p.Id, 10)
		p.Key = cmd5.MustEncryptString(strId)
		affected, errUpdate := session.ID(p.Id).Cols("key").Update(p)

		if errUpdate != nil {
			session.Rollback()
			return app.NewError(errUpdate)
		}

		if affected != 1 {
			session.Rollback()
			return app.NewError("更新错误")
		}
	}

	// 提交
	errCommit := session.Commit()
	if errCommit != nil {
		return app.NewError(errCommit)
	}

	return nil
}

// @title ModifyStatus
// @description 修改管理员状态
func (p Partners) ModifyStatus() (bool, error) {
	if p.Status == -1 {
		return false, app.NewError("对不起, 商户已经!")
	}

	status := 1
	if p.Status == 1 {
		status = 0
	}

	affected, err := app.Db().Table(new(Partners)).ID(p.Id).Cols("status").Update(map[string]int{"status": status})

	if err != nil {
		return false, app.NewError(err)
	}

	// 生效条数
	if affected == 0 {
		return false, app.NewError("对不起, 指定的ID更新数量不正确")
	}

	return true, nil
}

// 获取单个数据
// @param id int64 数据的id
// @return *Partners, error
func GetItemById(id int64) (*Partners, error) {
	item := new(Partners)
	has, err := app.Db().Where("id = ?", id).Get(item)

	if err != nil {
		return nil, err
	}

	if !has {
		return nil, app.NewError("对不起, 目标对象不存在")
	}

	return item, nil
}

// 获取单个数据
// @param sign string 数据的sign
// @return *Partners, error
func GetItemBySign(sign string) (*Partners, error) {
	item := new(Partners)
	has, err := app.Db().Where("partner_sign = ?", sign).Get(item)

	if err != nil {
		return nil, err
	}

	if !has {
		return nil, app.NewError("对不起, 目标对象不存在")
	}

	return item, nil
}

// 获取单个数据
// @title GetAllItemsFromDb
// @description 获取所有的租户
func GetAllItemsFromDb() (map[int64]*Partners, error) {
	items := make(map[int64]*Partners)
	err := app.Db().Find(&items)

	if err != nil {
		return nil, err
	}
	return items, nil
}

// @title GetPartnerSelectOptions
// @description 获取所有的商户选项
func GetPartnerSelectOptions() ([]map[string]interface{}, error) {
	items, err := GetAllPartnersFromCache()
	if err != nil {
		return nil, err
	}

	options := make([]map[string]interface{}, 0)
	for i, v := range items {
		options = append(options, map[string]interface{}{
			"label": v.PartnerName,
			"value": i,
		})
	}

	return options, nil
}

/** =============================  辅助函数 ============================= */

// 检测字段唯一性 如果存在返回false, 不存在返回true
func IsFieldExist(field string, value interface{}) bool {
	user := new(Partners)

	has, err := app.Db().Where(field+" = ?", value).Get(user)

	if err != nil {
		return false
	} else {
		if has {
			return false
		}
	}

	return true
}
